package com.ganmiao.server.sys.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.ganmiao.exception.DefaultBusinessException;
import com.ganmiao.server.sys.entity.SysDepartment;
import com.ganmiao.server.sys.query.SysDepartmentQuery;
import com.ganmiao.server.sys.repository.SysDepartmentRepository;
import com.ganmiao.server.sys.vo.SysDepartmentVo;
import com.ganmiao.server.sys.vo.SysUserVo;
import com.ganmiao.server.user.context.UserAuthContext;
import com.ganmiao.utils.StatusUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

/**
 * 部门信息
 */
@Service
public class SysDepartmentService {

    //部门信息
    @Autowired
    private SysDepartmentRepository sysDepartmentRepository;

    /**
     * 验证同级部门是否存在
     *
     * @param departmentName
     * @param parentId
     * @return
     */
    public boolean verifyDepartmentIsExist(String departmentName, Integer parentId) {

        //获取系统编码
        String sysCode = UserAuthContext.getSysCode();

        //获取用户信息
        SysUserVo loginUser = UserAuthContext.getLoginUser();

        //查询条件
        LambdaQueryWrapper<SysDepartment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDepartment::getSysCode, sysCode)
                .eq(loginUser.getSupplierId() != null, SysDepartment::getSupplierId, loginUser.getSupplierId())
                .eq(loginUser.getShopId() != null, SysDepartment::getShopId, loginUser.getShopId())
                .eq(SysDepartment::getDepartmentName, departmentName)
                .eq(SysDepartment::getParentId, parentId)
                .eq(SysDepartment::getStatus, StatusUtils.PASS);
        SysDepartment one = sysDepartmentRepository.getOne(queryWrapper);

        return !Objects.isNull(one);

    }

    /**
     * 获取子部门
     *
     * @param parentId
     * @param sysDepartmentList
     */
    public List<SysDepartmentVo> getChildMenu(Integer parentId, List<SysDepartment> sysDepartmentList) {

        //返回数据
        List<SysDepartmentVo> childMenus = new ArrayList<>();

        // 遍历所有节点，将父菜单id与传过来的id比较，相同则存入返回数据中
        sysDepartmentList.forEach(item -> {

            if (item.getParentId().equals(parentId)) {

                SysDepartmentVo sysDepartmentVo = new SysDepartmentVo();
                BeanUtils.copyProperties(item, sysDepartmentVo);
                childMenus.add(sysDepartmentVo);

            }

        });


        // 把子菜单的子菜单再循环一遍
        if (!CollectionUtils.isEmpty(childMenus)) {

            for (SysDepartmentVo child : childMenus) {

                child.setChildren(getChildMenu(child.getDepartmentId(), sysDepartmentList));

            }

        }

        //数据为空则停止循环
        if (childMenus.size() == 0) {

            return null;

        }

        return childMenus;

    }

    /**
     * 新增部门信息
     *
     * @param sysDepartment
     * @return
     */
    public boolean addSysDepartment(SysDepartment sysDepartment) {

        //获取系统编码并赋值
        String sysCode = UserAuthContext.getSysCode();
        sysDepartment.setSysCode(sysCode);
        SysUserVo loginUser = UserAuthContext.getLoginUser();
        if (loginUser.getSupplierId() != null) {
            sysDepartment.setSupplierId(loginUser.getSupplierId());
        }
        if (loginUser.getShopId() != null) {
            sysDepartment.setShopId(loginUser.getShopId());
        }

        //验证同级部门是否存在
        if (verifyDepartmentIsExist(sysDepartment.getDepartmentName(), sysDepartment.getParentId())) {

            throw new DefaultBusinessException("同级部门已存在");

        }

        return sysDepartmentRepository.save(sysDepartment);

    }

    /**
     * 删除部门信息
     *
     * @param sysDepartmentId
     * @return
     */
    public boolean deleteSysDepartment(@NotNull(message = "部门主键ID不能为空") Integer sysDepartmentId) {

        //删除条件
        LambdaUpdateWrapper<SysDepartment> updateWrapper = new LambdaUpdateWrapper<>();
        updateWrapper.eq(SysDepartment::getDepartmentId, sysDepartmentId)
                .set(SysDepartment::getStatus, StatusUtils.FAILURE);
        return sysDepartmentRepository.update(updateWrapper);

    }

    /**
     * 修改部门信息
     *
     * @param sysDepartment
     * @return
     */
    public boolean updateSysDepartment(SysDepartment sysDepartment) {

        //获取部门信息
        SysDepartment department = sysDepartmentRepository.getById(sysDepartment.getDepartmentId());

        //验证同级部门名称是否修改和同级部门是否存在
        if (!department.getDepartmentName().equals(sysDepartment.getDepartmentName()) && verifyDepartmentIsExist(sysDepartment.getDepartmentName(), sysDepartment.getParentId())) {

            throw new DefaultBusinessException("同级部门已存在");

        }

        return sysDepartmentRepository.updateById(sysDepartment);

    }

    /**
     * 获取部门信息 (所有)
     *
     * @param sysDepartmentQuery
     * @return
     */
    public List<SysDepartmentVo> getSysDepartmentList(SysDepartmentQuery sysDepartmentQuery) {

        //获取系统编码
        String sysCode = UserAuthContext.getSysCode();

        //获取用户信息
        SysUserVo loginUser = UserAuthContext.getLoginUser();

        //返回数据
        List<SysDepartmentVo> sysDepartmentVoList = new ArrayList<>();

        //菜单名称不为空 (条件查询)
        if (StringUtils.isNotBlank(sysDepartmentQuery.getDepartmentName())) {

            //查询条件
            LambdaQueryWrapper<SysDepartment> queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysDepartment::getSysCode, sysCode)
                    .eq(SysDepartment::getStatus, StatusUtils.PASS)
                    .eq(loginUser.getSupplierId() != null, SysDepartment::getSupplierId, loginUser.getSupplierId())
                    .eq(loginUser.getShopId() != null, SysDepartment::getShopId, loginUser.getShopId())
                    .like(SysDepartment::getDepartmentName, sysDepartmentQuery.getDepartmentName())
                    .orderByDesc(SysDepartment::getCreatedTime);
            //查询结果
            List<SysDepartment> parentResult = sysDepartmentRepository.list(queryWrapper);

            // 获取一级菜单
            if (!parentResult.isEmpty()) {

                //结果拷贝
                for (SysDepartment sysDepartment : parentResult) {

                    boolean anyMatch = parentResult.stream().anyMatch(item -> item.getDepartmentId().equals(sysDepartment.getParentId()));
                    if (!anyMatch) {
                        SysDepartmentVo sysDepartmentVo = new SysDepartmentVo();
                        BeanUtils.copyProperties(sysDepartment, sysDepartmentVo);
                        sysDepartmentVoList.add(sysDepartmentVo);
                    }

                }

                //获取子菜单
                if (!sysDepartmentVoList.isEmpty()) {

                    sysDepartmentVoList.forEach(item -> {

                        item.setChildren(getChildMenu(item.getDepartmentId(), parentResult));

                    });

                }

            }

            return sysDepartmentVoList;

        }

        //查询条件
        LambdaQueryWrapper<SysDepartment> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(SysDepartment::getSysCode, sysCode)
                .eq(SysDepartment::getStatus, StatusUtils.PASS)
                .eq(SysDepartment::getParentId, 0)
                .eq(loginUser.getSupplierId() != null, SysDepartment::getSupplierId, loginUser.getSupplierId())
                .eq(loginUser.getShopId() != null, SysDepartment::getShopId, loginUser.getShopId())
                .orderByDesc(SysDepartment::getCreatedTime);
        //查询结果
        List<SysDepartment> parentResult = sysDepartmentRepository.list(queryWrapper);


        //获取一级部门
        if (!parentResult.isEmpty()) {

            //结果拷贝
            parentResult.forEach(item -> {

                SysDepartmentVo sysDepartmentVo = new SysDepartmentVo();
                BeanUtils.copyProperties(item, sysDepartmentVo);
                sysDepartmentVoList.add(sysDepartmentVo);

            });

            //查询条件
            queryWrapper = new LambdaQueryWrapper<>();
            queryWrapper.eq(SysDepartment::getSysCode, sysCode)
                    .eq(SysDepartment::getStatus, StatusUtils.PASS)
                    .ne(SysDepartment::getParentId, 0)
                    .eq(loginUser.getSupplierId() != null, SysDepartment::getSupplierId, loginUser.getSupplierId())
                    .eq(loginUser.getShopId() != null, SysDepartment::getShopId, loginUser.getShopId())
                    .orderByDesc(SysDepartment::getCreatedTime);
            //查询结果
            List<SysDepartment> sysDepartmentList = sysDepartmentRepository.list(queryWrapper);

            //获取子菜单
            if (!sysDepartmentVoList.isEmpty()) {

                sysDepartmentVoList.forEach(item -> {

                    item.setChildren(getChildMenu(item.getDepartmentId(), sysDepartmentList));

                });

            }

        }

        return sysDepartmentVoList;

    }

    /**
     * 获取部门信息 (详情)
     *
     * @param departmentId
     * @return
     */
    public SysDepartment getSysDepartment(@NotNull(message = "部门主键ID不能为空") Integer departmentId) {

        return sysDepartmentRepository.getById(departmentId);


    }

}
